package net.dfx.iot_download_tool.impl;

import java.io.File;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;

import net.dfx.iot_download_tool.enu.LocalZoneEnum;
import net.dfx.iot_download_tool.enu.TimeModeEnum;
import net.dfx.iot_download_tool.enu.TimePrefixEnum;
import net.dfx.iot_download_tool.enu.TimeUnitEnum;
import net.dfx.iot_download_tool.itf.IUserEnter;
import net.dfx.iot_download_tool.vo.LocalSETimeVO;
import net.dfx.iot_download_tool.vo.UserEnterVO;

public class UserEnterImpl implements IUserEnter {
	
	@Override
	public UserEnterVO getAllUserEnter() {
		UserEnterVO ueVO = new UserEnterVO();
		String pathPre = this.excelPathPre();
		ueVO.setExcelPathPre(pathPre);
		List<String> equipEnter = this.equipEnter();
		ueVO.setEquipName(equipEnter);
		List<String> paramEnter = this.paramEnter();
		ueVO.setParamName(paramEnter);
		TimeModeEnum timeMode = this.timeMode();
		switch (timeMode) {
		case ONEDATE:
			LocalSETimeVO deOneDay = this.dateEnter();
			if (deOneDay != null) {
				List<LocalSETimeVO> eOneDayVO = new ArrayList<>();
				eOneDayVO.add(deOneDay);
				ueVO.setDatetimeRang(eOneDayVO);
			}
			break;
		case RANGDATE:
			List<LocalSETimeVO> deDateRang = this.dateRangEnter();
			if (deDateRang!=null && !deDateRang.isEmpty()) {
				ueVO.setDatetimeRang(deDateRang);
			}
			break;
		case ONEDATETIME:
			LocalSETimeVO deDatetime = this.datetimeEnter();
			if (deDatetime != null) {
				List<LocalSETimeVO> eDatetimeVO = new ArrayList<>();
				eDatetimeVO.add(deDatetime);
				ueVO.setDatetimeRang(eDatetimeVO);
			}
			break;
		case RANGDATETIME:
			List<LocalSETimeVO> deDatetimeRang = this.datetimeRangEnter();
			if (deDatetimeRang!=null && !deDatetimeRang.isEmpty()) {
				ueVO.setDatetimeRang(deDatetimeRang);
			}
			break;
		default:
			// 默认什么也不做
			break;
		}
		return ueVO;
	}

	@Override
	public String excelPathPre() {
		Scanner sc = new Scanner(System.in);
		// 获取用户主目录
		String userHome = System.getProperty("user.home");
		// 拼接下载目录路径
		String pathPre = userHome + File.separator + "Downloads";
		// System.out.println("请输入excel文件要保存到的文件夹，或者直接回车，默认保存到 下载 目录");
		// 输出蓝色
		System.out.format("\33[%d;%s\33[0m %n", 34, "请输入excel文件要保存到的文件夹完整路径，默认保存到 下载 目录");
		String pathPreT = sc.nextLine();
		if (StringUtils.isNotBlank(pathPreT)) {
			pathPre = pathPreT;
			// 输出绿色，31-红色，32-绿色，33-黄色
			System.out.format("\33[%d;%s\33[0m %n", 32, pathPre);
		}
		sc.close();
		return pathPre;
	}

	@Override
	public List<String> equipEnter() {
		Scanner sc = new Scanner(System.in);
		System.out.format("\33[%d;%s\33[0m %n", 34, "请输入一个待查询设备名称，之后按下回车键");
		String enterStr = sc.nextLine();
		List<String> equipStrs = new ArrayList<>();
		if (StringUtils.isNotBlank(enterStr)) {
			if (enterStr.contains(",")) {
				equipStrs = Arrays.stream(enterStr.split(",")).filter(s -> !s.isEmpty()).collect(Collectors.toList());
			} else {
				equipStrs.add(enterStr);
			}
			System.out.format("\33[%d;%s\33[0m %n", 32, "读取完成");
		}
		sc.close();
		return null;
	}

	@Override
	public List<String> paramEnter() {
		Scanner sc = new Scanner(System.in);
		System.out.format("\33[%d;%s\33[0m %n", 34, "请输入待查询参数，多个参数用英文逗号隔开，之后按下回车键");
		String allParamsStr = sc.nextLine();
		List<String> allParams = new ArrayList<>();
		if (StringUtils.isNotBlank(allParamsStr)) {
			if (allParamsStr.contains(",")) {
				allParams = Arrays.stream(allParamsStr.split(",")).filter(s -> !s.isEmpty()).collect(Collectors.toList());
			} else {
				allParams.add(allParamsStr);
			}
			System.out.format("\33[%d;%s\33[0m %n", 32, "读取完成");
		}
		sc.close();
		return allParams;
	}
	
	@Override
	public TimeModeEnum timeMode() {
		Scanner sc = new Scanner(System.in);
		System.out.format("%s%n%s%n%s%n%s%n\33[%d;%s\33[0m %n", "1-仅输入一个日期，例如：2025-08-14", "2-输入一对或多对日期范围，例如：2025-07-24,2025-07-25,2025-08-14,2025-08-15", "3-输入一个日期时间，例如：2025-07-24 10:00:01", "4-输入一个或多个日期时间范围，例如：2025-07-24 10:00:01,2025-07-25 08:59:59,2025-08-14 10:00:01,2025-08-15 08:59:59", 34, "请输入一个数字编号");
		String numStr = sc.nextLine();
		TimeModeEnum timeNum = TimeModeEnum.NONEMODE;
		if (StringUtils.isNotBlank(numStr)) {
			switch (numStr) {
			case "1":
				timeNum = TimeModeEnum.ONEDATE;
				break;
			case "2":
				timeNum = TimeModeEnum.RANGDATE;
				break;
			case "3":
				timeNum = TimeModeEnum.ONEDATETIME;
				break;
			case "4":
				timeNum = TimeModeEnum.RANGDATETIME;
				break;
			default:
				System.out.format("\33[%d;%s\33[0m %n", 31, "日期模式输入异常，程序终止执行！");
				break;
			}
		}
		sc.close();
		System.out.format("\33[%d;%s\33[0m %n", 32, "读取完成");
		return timeNum;
	}

	@Override
	public LocalSETimeVO dateEnter() {
		Scanner sc = new Scanner(System.in);
		System.out.format("\33[%d;%s\33[0m %n", 34, "请输入一个日期，例如：2025-08-14");
		String aa = sc.nextLine();
		// 要返回的VO类，封装完成后返回
		LocalSETimeVO lsetVo = new LocalSETimeVO();
		if (StringUtils.isNotBlank(aa)) {
			TimePrefixEnum tpe = this.prefixMode();
			long btd = this.betweenDay();
			TimeUnitEnum tue = this.unitMode();
			
			DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
			LocalZoneEnum lze = LocalZoneEnum.CHINAZONE;
			
			switch (tpe) {
			case MINUSSIGN:
				// 往更早的时间方向追溯
				String aac = aa+" 23:59:59";
				LocalDateTime endLDT = LocalDateTime.parse(aac, dtf);
				ZonedDateTime endZDT = endLDT.atZone(lze.getZone());
				ZonedDateTime startZDT = null;
				switch (tue) {
				case HOUR:
					// 单位是小时
					startZDT = endZDT.minusHours(btd);
					break;
				case DAY:
					// 单位是日
					startZDT = endZDT.minusDays(btd);
					break;
				case WEEK:
					// 单位是周
					startZDT = endZDT.minusWeeks(btd);
					break;
				case MONTH:
					// 单位是月
					startZDT = endZDT.minusMonths(btd);
					break;
				case YEAR:
					// 单位是年
					startZDT = endZDT.minusYears(btd);
					break;
				default:
					// 默认按照天处理
					startZDT = endZDT.minusDays(btd);
					break;
				}
				lsetVo.setDateStr(aa);
				lsetVo.setStartT(startZDT);
				lsetVo.setEndT(endZDT);
				break;
			case PLUSSIGN:
				// 往更晚的时间方向追溯
				String alc = aa+" 00:00:01";
				LocalDateTime startLLDT = LocalDateTime.parse(alc, dtf);
				ZonedDateTime startLZDT = startLLDT.atZone(lze.getZone());
				ZonedDateTime endLZDT = null;
				switch (tue) {
				case HOUR:
					// 单位是小时
					endLZDT = startLZDT.plusHours(btd);
					break;
				case DAY:
					// 单位是日
					endLZDT = startLZDT.plusDays(btd);
					break;
				case WEEK:
					// 单位是周
					endLZDT = startLZDT.plusWeeks(btd);
					break;
				case MONTH:
					// 单位是月
					endLZDT = startLZDT.plusMonths(btd);
					break;
				case YEAR:
					// 单位是年
					endLZDT = startLZDT.plusYears(btd);
					break;
				default:
					// 默认按照天处理
					endLZDT = startLZDT.plusDays(btd);
					break;
				}
				lsetVo.setDateStr(aa);
				lsetVo.setStartT(startLZDT);
				lsetVo.setEndT(endLZDT);
				break;
			default:
				// 默认什么也不做
				break;
			}
		}
		sc.close();
		return lsetVo;
	}

	@Override
	public List<LocalSETimeVO> dateRangEnter() {
		Scanner sc = new Scanner(System.in);
		System.out.format("\33[%d;%s\33[0m %n", 34, "请输入一个或多个日期范围，例如：2025-08-14,2025-08-18");
		String aa = sc.nextLine();
		
		List<LocalSETimeVO> lsetVOs = new ArrayList<>();
		if (StringUtils.isNotBlank(aa)) {
			if (aa.contains(",")) {
				List<String> ab = Arrays.stream(aa.split(",")).filter(s -> !s.isEmpty()).collect(Collectors.toList());
				// 循环遍历，每两个作为一组放入VO中
				int allNum = ab.size();
				int halfNum = allNum / 2;
				DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
				LocalZoneEnum lze = LocalZoneEnum.CHINAZONE;
				for (int i = 0; i < halfNum; i++) {
					int si = 2*i;
					int ei = 2*(i+1)-1;
					String sd = ab.get(si)+" 00:00:01";
					String ed = ab.get(ei)+" 23:59:59";
					LocalDateTime sLDT = LocalDateTime.parse(sd, dtf);
					LocalDateTime eLDT = LocalDateTime.parse(ed, dtf);
					ZonedDateTime sZDT = sLDT.atZone(lze.getZone());
					ZonedDateTime eZDT = eLDT.atZone(lze.getZone());
					LocalSETimeVO lsetVO = new LocalSETimeVO();
					// 对于输入的其中一个日期范围而言，可以把日期字符串保留范围的右边界
					lsetVO.setDateStr(ab.get(ei));
					lsetVO.setStartT(sZDT);
					lsetVO.setEndT(eZDT);
					
					lsetVOs.add(lsetVO);
				}
			}
		}
		sc.close();
		return lsetVOs;
	}

	@Override
	public LocalSETimeVO datetimeEnter() {
		Scanner sc = new Scanner(System.in);
		System.out.format("\33[%d;%s\33[0m %n", 34, "请输入一个日期时间，例如：2025-08-14 08:37:23");
		String aa = sc.nextLine();
		// 要返回的VO类，封装完成后返回
		LocalSETimeVO lsetVo = new LocalSETimeVO();
		if (StringUtils.isNotBlank(aa)) {
			TimePrefixEnum tpe = this.prefixMode();
			long btd = this.betweenDay();
			TimeUnitEnum tue = this.unitMode();
			
			DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
			LocalZoneEnum lze = LocalZoneEnum.CHINAZONE;
			String dateStr = aa.substring(0, 10);
			
			switch (tpe) {
			case MINUSSIGN:
				// 往更早的时间方向追溯
				LocalDateTime endLDT = LocalDateTime.parse(aa, dtf);
				ZonedDateTime endZDT = endLDT.atZone(lze.getZone());
				ZonedDateTime startZDT = null;
				switch (tue) {
				case HOUR:
					// 单位是小时
					startZDT = endZDT.minusHours(btd);
					break;
				case DAY:
					// 单位是日
					startZDT = endZDT.minusDays(btd);
					break;
				case WEEK:
					// 单位是周
					startZDT = endZDT.minusWeeks(btd);
					break;
				case MONTH:
					// 单位是月
					startZDT = endZDT.minusMonths(btd);
					break;
				case YEAR:
					// 单位是年
					startZDT = endZDT.minusYears(btd);
					break;
				default:
					// 默认按照天处理
					startZDT = endZDT.minusDays(btd);
					break;
				}
				lsetVo.setDateStr(dateStr);
				lsetVo.setStartT(startZDT);
				lsetVo.setEndT(endZDT);
				break;
			case PLUSSIGN:
				// 往更晚的时间方向追溯
				LocalDateTime startLLDT = LocalDateTime.parse(aa, dtf);
				ZonedDateTime startLZDT = startLLDT.atZone(lze.getZone());
				ZonedDateTime endLZDT = null;
				switch (tue) {
				case HOUR:
					// 单位是小时
					endLZDT = startLZDT.plusHours(btd);
					break;
				case DAY:
					// 单位是日
					endLZDT = startLZDT.plusDays(btd);
					break;
				case WEEK:
					// 单位是周
					endLZDT = startLZDT.plusWeeks(btd);
					break;
				case MONTH:
					// 单位是月
					endLZDT = startLZDT.plusMonths(btd);
					break;
				case YEAR:
					// 单位是年
					endLZDT = startLZDT.plusYears(btd);
					break;
				default:
					// 默认按照天处理
					endLZDT = startLZDT.plusDays(btd);
					break;
				}
				lsetVo.setDateStr(dateStr);
				lsetVo.setStartT(startLZDT);
				lsetVo.setEndT(endLZDT);
				break;
			default:
				// 默认什么也不做
				break;
			}
		}
		sc.close();
		return lsetVo;
	}

	@Override
	public List<LocalSETimeVO> datetimeRangEnter() {
		Scanner sc = new Scanner(System.in);
		System.out.format("\33[%d;%s\33[0m %n", 34, "请输入一个或多个日期时间范围，例如：2025-08-14 00:00:01,2025-08-17 23:59:59");
		String aa = sc.nextLine();
		
		List<LocalSETimeVO> lsetVOs = new ArrayList<>();
		if (StringUtils.isNotBlank(aa)) {
			if (aa.contains(",")) {
				List<String> ab = Arrays.stream(aa.split(",")).filter(s -> !s.isEmpty()).collect(Collectors.toList());
				// 循环遍历，每两个作为一组放入VO中
				int allNum = ab.size();
				int halfNum = allNum / 2;
				DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
				LocalZoneEnum lze = LocalZoneEnum.CHINAZONE;
				for (int i = 0; i < halfNum; i++) {
					int si = 2*i;
					int ei = 2*(i+1)-1;
					String sd = ab.get(si);
					String ed = ab.get(ei);
					String dateStr = ed.substring(0, 10);
					LocalDateTime sLDT = LocalDateTime.parse(sd, dtf);
					LocalDateTime eLDT = LocalDateTime.parse(ed, dtf);
					ZonedDateTime sZDT = sLDT.atZone(lze.getZone());
					ZonedDateTime eZDT = eLDT.atZone(lze.getZone());
					LocalSETimeVO lsetVO = new LocalSETimeVO();
					// 对于输入的其中一个日期范围而言，可以把日期字符串保留范围的右边界
					lsetVO.setDateStr(dateStr);
					lsetVO.setStartT(sZDT);
					lsetVO.setEndT(eZDT);
					
					lsetVOs.add(lsetVO);
				}
			}
		}
		sc.close();
		return lsetVOs;
	}

	@Override
	public TimePrefixEnum prefixMode() {
		Scanner sc = new Scanner(System.in);
		System.out.format("%s%n%s%n\33[%d;%s\33[0m %n", "1-往后追溯时间，例如：2025-08-01则向2025-08-12方向追溯", "2-往前追溯时间，例如：2025-08-01则向2025-07-20方向追溯", 34, "请输入一个序号");
		String aa = sc.nextLine();
		// 要返回的enum对象
		TimePrefixEnum tpe = null;
		if (StringUtils.isNotBlank(aa)) {
			switch (aa) {
			case "1":
				tpe = TimePrefixEnum.PLUSSIGN;
				break;
			case "2":
				tpe = TimePrefixEnum.MINUSSIGN;
				break;
			default:
				break;
			}
		}
		sc.close();
		return tpe;
	}

	@Override
	public long betweenDay() {
		Scanner sc = new Scanner(System.in);
		System.out.format("\33[%d;%s\33[0m %n", 34, "请输入整数");
		String aa = sc.nextLine();
		long btd = 0L;
		if (StringUtils.isNotBlank(aa)) {
			Long ab = Long.valueOf(aa);
			if (ab!=null) {
				btd = ab;
			}
		}
		sc.close();
		return btd;
	}

	@Override
	public TimeUnitEnum unitMode() {
		Scanner sc = new Scanner(System.in);
		System.out.format("%s%n%s%n%s%n%s%n%s%n\33[%d;%s\33[0m %n", "1-以小时为单位", "2-以天为单位", "3-以周为单位", "4-以月为单位", "5-以年为单位", 34, "请输入编号");
		String aa = sc.nextLine();
		
		TimeUnitEnum tue = null;
		if (StringUtils.isNotBlank(aa)) {
			switch (aa) {
			case "1":
				tue = TimeUnitEnum.HOUR;
				break;
			case "2":
				tue = TimeUnitEnum.DAY;
				break;
			case "3":
				tue = TimeUnitEnum.WEEK;
				break;
			case "4":
				tue = TimeUnitEnum.MONTH;
				break;
			case "5":
				tue = TimeUnitEnum.YEAR;
				break;
			default:
				break;
			}
		}
		sc.close();
		return tue;
	}

}
